#include "const.h"
#include "ChatGrpcServiceImpl.h"
#include "RedisManager.h"
#include "MysqlManager.h"
#include "UserManager.h"
#include "CSession.h"

#include <json/reader.h>
#include <json/value.h>


grpc::Status ChatGrpcServiceImpl::NotifyAddFriend(grpc::ServerContext* context, const message::AddFriendReq* request, message::AddFriendRsp* response)
{
    // 查找用户是否在本服务器上
    auto touid = request->touid();
    auto session = UserManager::getInstance()->getSession(touid);

    Defer defer([request, response]() {
        response->set_error(ErrorCodes::Success);
        response->set_applyuid(request->applyuid());
        response->set_touid(request->touid());
    });

    // 如果用户不在内存中，则直接返回 
    if (session == nullptr) {
        return grpc::Status::OK;
    }

    // 如果用户在内存中，则直接向对方发送消息
    Json::Value  rtvalue;
    rtvalue["error"] = ErrorCodes::Success;
    rtvalue["applyuid"] = request->applyuid();
    rtvalue["name"] = request->name();
    rtvalue["desc"] = request->desc();
    rtvalue["icon"] = request->icon();
    rtvalue["sex"] = request->sex();
    rtvalue["nick"] = request->nick();

    std::string return_str = rtvalue.toStyledString();

    session->Send(return_str, ID_NOTIFY_ADD_FRIEND_REQ);

    return grpc::Status::OK;
}

grpc::Status ChatGrpcServiceImpl::NotifyAuthFriend(grpc::ServerContext* context, const message::AuthFriendReq* request, message::AuthFriendRsp* response)
{
    // 查找用户是否在本服务器
    auto touid = request->touid();
    auto fromuid = request->fromuid();
    auto session = UserManager::getInstance()->getSession(touid);

    Defer defer([request, response]() {
        response->set_error(ErrorCodes::Success);
        response->set_fromuid(request->fromuid());
        response->set_touid(request->touid());
    });

    // 用户不在线，则直接返回
    if (session == nullptr) {
        return grpc::Status::OK;
    }

    // 在内存中则直接发送通知对方
    Json::Value rtvalue;
    rtvalue["error"] = ErrorCodes::Success;
    rtvalue["fromuid"] = request->fromuid();
    rtvalue["touid"] = request->touid();

    std::string base_key = USER_BASE_INFO + std::to_string(fromuid);
    auto user_info = std::make_shared<UserInfo>();
    bool b_info = getBaseInfo(base_key, fromuid, user_info);
    if (b_info) {
        rtvalue["name"] = user_info->name;
        rtvalue["nick"] = user_info->nick;
        rtvalue["icon"] = user_info->icon;
        rtvalue["sex"] = user_info->sex;
    }
    else {
        rtvalue["error"] = ErrorCodes::UidInvalid;
    }

    std::string return_str = rtvalue.toStyledString();

    session->Send(return_str, ID_NOTIFY_AUTH_FRIEND_REQ);
    return grpc::Status::OK;
}

grpc::Status ChatGrpcServiceImpl::NotifyTextChatMsg(grpc::ServerContext* context, const message::TextChatMsgReq* request, message::TextChatMsgRsp* response)
{
    // 查找用户是否在本服务器
    auto touid = request->touid();
    auto session = UserManager::getInstance()->getSession(touid);
    response->set_error(ErrorCodes::Success);

    // 用户不在内存中则直接返回
    if (session == nullptr) {
        return grpc::Status::OK;
    }

    // 在内存中则直接发送通知对方
    Json::Value  rtvalue;
    rtvalue["error"] = ErrorCodes::Success;
    rtvalue["fromuid"] = request->fromuid();
    rtvalue["touid"] = request->touid();

    // 将聊天数据组织为数组
    Json::Value text_array;
    for (auto& msg : request->textmsgs()) {
        Json::Value element;
        element["content"] = msg.msgcontent();
        element["msgid"] = msg.msgid();
        text_array.append(element);
    }
    rtvalue["text_array"] = text_array;

    std::string return_str = rtvalue.toStyledString();

    session->Send(return_str, ID_NOTIFY_TEXT_CHAT_MSG_REQ);

    return grpc::Status::OK;
}

bool ChatGrpcServiceImpl::getBaseInfo(std::string base_key, int uid, std::shared_ptr<UserInfo>& userinfo)
{
    // 优先查redis中查询用户信息
    std::string info_str = "";
    bool b_base = RedisManager::getInstance()->get(base_key, info_str);
    if (b_base) {
        Json::Reader reader;
        Json::Value root;
        reader.parse(info_str, root);
        userinfo->uid = root["uid"].asInt();
        userinfo->name = root["name"].asString();
        userinfo->pwd = root["pwd"].asString();
        userinfo->email = root["email"].asString();
        userinfo->nick = root["nick"].asString();
        userinfo->desc = root["desc"].asString();
        userinfo->sex = root["sex"].asInt();
        userinfo->icon = root["icon"].asString();
        std::cout << "user login uid is  " << userinfo->uid << " name  is " << userinfo->name 
                  << " pwd is " << userinfo->pwd << " email is " << userinfo->email 
                  << std::endl;
    } else {
        // redis中没有则查询mysql数据库
        std::shared_ptr<UserInfo> user_info = nullptr;
        user_info = MysqlManager::getInstance()->getUserInfo(uid);
        if (user_info == nullptr) {
            return false;
        }

        userinfo = user_info;

        // 将数据库内容写入redis缓存
        Json::Value redis_root;
        redis_root["uid"] = uid;
        redis_root["pwd"] = userinfo->pwd;
        redis_root["name"] = userinfo->name;
        redis_root["email"] = userinfo->email;
        redis_root["nick"] = userinfo->nick;
        redis_root["desc"] = userinfo->desc;
        redis_root["sex"] = userinfo->sex;
        redis_root["icon"] = userinfo->icon;
        RedisManager::getInstance()->set(base_key, redis_root.toStyledString());
    }

    return true;
}
